/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package nexus.foros;

import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.Statement;
import java.sql.Types;
import java.util.ArrayList;
import nexus.adec.Coneccion;
import nexus.adec.GrupoAcademico;

/**
 *
 * @author Rodrigo
 */
public class GestorForosDB {
    
    private Coneccion con;
    
    public GestorForosDB(){
        con = Coneccion.getInstance();
    }
    
    private String obtenerCodigoForo(){
        String res = "";
        try {
            Connection c = con.getConnection();
            PreparedStatement pss = c.prepareStatement("select nextval('foro_seq');");
            ResultSet rs = pss.executeQuery();
            rs.next();
            res = "FORO"+rs.getInt(1);
            rs.close();
            pss.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return res;
    }
    
    public void publicarForo(String codigoEspacio,String nombreUsuario,Foro f){
        String codigoForo = obtenerCodigoForo();
        try {
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("insert into foro values(?,?,?,?,?,?,?,?);");
            ps.setString(1, codigoForo);
            ps.setString(2, codigoEspacio);
            ps.setNull(3, Types.VARCHAR);
            ps.setString(4, nombreUsuario);
            ps.setString(5, f.getTituloForo());
            ps.setDate(6, new Date(f.getFechaPublicacion().getTime()));
            ps.setString(7, f.getContenido());
            ps.setBoolean(8, f.isPublicado());
            ps.executeUpdate();
            ps.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public ArrayList<Foro> listarForosUsuarioAdm(String nombreUsuario,String codigoEspacio){
        ArrayList<Foro> res = new ArrayList<Foro>();
        try {
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("select * from foro where nombre_usuario=? and codigo_espacio=?;");
            ps.setString(1, nombreUsuario);
            ps.setString(2, codigoEspacio);
            ResultSet rs = ps.executeQuery();
            while(rs.next()){
                if(rs.getString("for_codigo_foro")==null)
                    res.add(new Foro(rs.getString("codigo_foro"), rs.getString("titulo_foro"), rs.getDate("fecha_publicacion"), rs.getString("contenido"),rs.getBoolean("publicado")));
            }
            rs.close();
            ps.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return res;
    }
    
    
    
    public void eliminarForo(String codigoForo){
        try {
            Connection c = con.getConnection();
            Statement stm = c.createStatement();
            stm.executeUpdate("delete from asignacion_foro where codigo_foro='"+codigoForo+"';");
            stm.executeUpdate("delete from foro where for_codigo_foro='"+codigoForo+"';");
            stm.executeUpdate("delete from foro where codigo_foro='"+codigoForo+"';");
            stm.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public ArrayList<Foro> recuperarRespuestas(String codigoForo){
        ArrayList<Foro> res = new ArrayList<Foro>();
        try {
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("select * from foro where for_codigo_foro=?;");
            ps.setString(1, codigoForo);
            ResultSet rs = ps.executeQuery();
            while(rs.next()){
                if(rs.getBoolean("publicado"))
                res.add( new Foro(rs.getString("codigo_foro"),rs.getString("titulo_foro"),rs.getDate("fecha_publicacion"),rs.getString("contenido"),rs.getBoolean("publicado"),obtenerCreadorForo(rs.getString("codigo_foro"))) );
            }
            rs.close();
            ps.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return res;
    }
    
    public void actualizarForo(Foro f){
        try {
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("update foro set titulo_foro=?, contenido=?, publicado=? where codigo_foro=?;");
            ps.setString(1, f.getTituloForo());
            ps.setString(2, f.getContenido());
            ps.setBoolean(3, f.isPublicado());
            ps.setString(4, f.getCodigoForo());
            ps.executeUpdate();
            ps.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public void publicarRespuesta(String codigoPadre,String codigoEspacio,String nombreUsuario,Foro respuesta){
        String codigoForo = obtenerCodigoForo();
        try {
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("insert into foro values(?,?,?,?,?,?,?,?);");
            ps.setString(1, codigoForo);
            ps.setString(2, codigoEspacio);
            ps.setString(3, codigoPadre);
            ps.setString(4, nombreUsuario);
            ps.setString(5, respuesta.getTituloForo());
            ps.setDate(6, new Date(respuesta.getFechaPublicacion().getTime()));
            ps.setString(7, respuesta.getContenido());
            ps.setBoolean(8, respuesta.isPublicado());
            ps.executeUpdate();
            ps.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public Foro obtenerForo(String codigoForo){
        Foro res = null;
        try {
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("select * from foro where codigo_foro=?;");
            ps.setString(1, codigoForo);
            ResultSet rs = ps.executeQuery();
            if(rs.next()){
                res = new Foro(rs.getString("codigo_foro"), rs.getString("titulo_foro"), rs.getDate("fecha_publicacion"), rs.getString("contenido"),rs.getBoolean("publicado"),obtenerCreadorForo(codigoForo));
            }
            rs.close();
            ps.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return res;
    }
    
    public void asignarPreferencias(String codigoForo,String codigoEspacio,ArrayList<GrupoAcademico> grupos,ArrayList<String> roles){
        try {
            Connection c = con.getConnection();
            Statement stm = c.createStatement();
            PreparedStatement ps = c.prepareStatement("insert into asignacion_foro values(?,?,?,?,?,?);");
            stm.executeUpdate("delete from asignacion_foro where codigo_foro='"+codigoForo+"';");
            for(GrupoAcademico g :grupos){
                for(String rol:roles){
                    ps.setString(1, g.getCodigoMateria());
                    ps.setString(2, g.getCodigoCarrera());
                    ps.setString(3, codigoEspacio);
                    ps.setString(4, g.getNumeroGrupo());
                    ps.setString(5, codigoForo);
                    ps.setString(6, rol);
                    ps.executeUpdate();
                }
            }
            ps.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public ArrayList<Foro> listarForosUsuario(String nombreUsuario,String codigoEspacio){
        ArrayList<Foro> res = new ArrayList<Foro>();
        try {
            String rol = obtenerRolUsuario(nombreUsuario,codigoEspacio);
            if(rol.equals("Responsable")){
                res = listarForosEspacio(codigoEspacio);
            }else{
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("select * from asignacion_academica where nombre_usuario=? and codigo_espacio=?;");
            ps.setString(1, nombreUsuario);
            ps.setString(2, codigoEspacio);
            ResultSet rs = ps.executeQuery();
            PreparedStatement pss = c.prepareStatement("select * from asignacion_foro where codigo_espacio=? and codigo_carrera=? and codigo_materia=? and numero_grupo=? and codigo_rol=?;");
            while(rs.next()){
                pss.setString(1, codigoEspacio);
                pss.setString(2, rs.getString("codigo_carrera"));
                pss.setString(3, rs.getString("codigo_materia"));
                pss.setString(4, rs.getString("numero_grupo"));
                pss.setString(5, rol);
                ResultSet rss = pss.executeQuery();
                while(rss.next()){
                    if(esPadre(rss.getString("codigo_foro"))){
                        Foro f = obtenerForo(rss.getString("codigo_foro")); 
                        if(f.isPublicado()) res.add(f);
                    }
                }
                rss.close();
            }
            rs.close();
            pss.close();
            ps.close();
            //c.close();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return res;
    }
    
    public boolean esPadre(String codigoForo){
        boolean res = false;
        try {
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("select * from foro where codigo_foro=?;");
            ps.setString(1, codigoForo);
            ResultSet rs = ps.executeQuery();
            if(rs.next()){
                if(rs.getString("for_codigo_foro")==null){
                    res = true;
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return res;
    }
    
    public ArrayList<Foro> listarForosEspacio(String codigoEspacio){
        ArrayList<Foro> res = new ArrayList<Foro>();
        try {
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("select * from foro where codigo_espacio=?;");
            ps.setString(1, codigoEspacio);
            ResultSet rs = ps.executeQuery();
            while(rs.next()){
                if(esPadre(rs.getString("codigo_foro")) && rs.getBoolean("publicado")){
                    res.add(new Foro(rs.getString("codigo_foro"), rs.getString("titulo_foro"), rs.getDate("fecha_publicacion"), rs.getString("contenido"), rs.getBoolean("publicado"),obtenerCreadorForo(rs.getString("codigo_foro"))));
                }
            }
            rs.close();
            ps.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return res;
    }
    
    public String obtenerRolUsuario(String nombreUsuario,String codigoEspacio){
        String res = "";
        try {
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("select * from asignacion_espacio where nombre_usuario=? and codigo_espacio=?;");
            ps.setString(1, nombreUsuario);
            ps.setString(2, codigoEspacio);
            ResultSet rs = ps.executeQuery();
            if(rs.next()){
                res = rs.getString("codigo_rol");
            }
            rs.close();
            ps.close();
            //c.close();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return res;
    }
    
    public String obtenerCreadorForo(String codigoForo){
        String res = "";
        try {
            Connection c = con.getConnection();
            PreparedStatement ps = c.prepareStatement("select * from foro where codigo_foro=?;");
            ps.setString(1, codigoForo);
            ResultSet rs = ps.executeQuery();
            if(rs.next()){
                res = rs.getString("nombre_usuario");
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
        return res;
    }
    
    public static GestorForosDB getInstance(){
        return new GestorForosDB();
    }
    
    public static void main(String[] args) {
        GestorForosDB database = getInstance();
        //database.publicarForo("ESP16", "199902367", new Foro("FORO DE PRUEBA", new java.util.Date(), "ES UN NUEVO FORO",true));
        /*ArrayList<GrupoAcademico> grupos = new ArrayList<GrupoAcademico>();
        ArrayList<String> roles = new ArrayList<String>();
        roles.add("Estudiante");
        grupos.add(new GrupoAcademico("419701", "2010010", "2"));
        database.asignarPreferencias("FORO19", "ESP16", grupos,roles);*/
        //System.out.println(database.listarForosUsuario("rodrigo"));
        //database.actualizarForo(new Foro("FORO10","NUEVO FORO", new java.util.Date(), "ESE ES UN FORO",true));
        //database.eliminarForo("FORO10");
        //database.publicarRespuesta("FORO11", "ESP14", "juampi", new Foro("NO HAY SOLUCION", new java.util.Date(), "NO SE PUEDE", true));
        //System.out.println(database.listarForosUsuario("200111122", "ESP16").size());
        //System.out.println(database.obtenerCreadorForo("FORO11"));
        //System.out.println(database.listarForosEspacio("ESP16").size());
        /*ArrayList<Foro> foros = database.listarForosUsuario("200111122");
        for(Foro f:foros){
            System.out.println(f.getCodigoForo());
        }*/
        System.out.println(database.listarForosUsuarioAdm("rodrigo", "ESP16"));
    }
}
